package com.agp.service.impl;

import com.agp.constant.MessageConstant;
import com.agp.constant.StatusConstant;
import com.agp.context.BaseContext;
import com.agp.dto.*;
import com.agp.entity.User;
import com.agp.exception.AccountNotFoundException;
import com.agp.mapper.UserMapper;
import com.agp.result.PageResult;
import com.agp.service.UserService;
import com.agp.utils.SMSUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SMSUtil smsUtil;


    /**
     * 登录
     *
     * @param userLoginDTO
     * @param isPasswordLogin
     */
    public User login(UserLoginDTO userLoginDTO, boolean isPasswordLogin) {
        String phone = userLoginDTO.getPhone();
        String password = userLoginDTO.getPassword();
        String captcha = userLoginDTO.getCaptcha();
        // 1、根据手机号查询数据库中的数据
        User user = userMapper.selectUserByPhone(phone);
        // 2、处理各种异常情况（用户不存在、密码不对、账号被锁定）
        if (user == null) {
            // ACCOUNT_NOT_FOUND:账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        if (user.getStatus() == StatusConstant.ACCOUNT_LOCKED) {
            // ACCOUNT_LOCKED:账号被锁定
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_LOCKED);
        }
        //  判断是密码登录还是验证码登录
        if (isPasswordLogin) {
            //  密码登录
            password = DigestUtils.md5DigestAsHex(password.getBytes());
            if (!password.equals(user.getPassword())) {
                // PASSWORD_ERROR:密码错误
                throw new AccountNotFoundException(MessageConstant.PASSWORD_ERROR);
            }
        } else {
            // 验证码登录
            // 验证验证码是否正确
            smsUtil.checkCaptcha(phone, captcha);
        }
        return user;
    }

    /**
     * 根据用户id查询用户角色
     *
     * @param currentId
     */
    @Override
    public Integer getRoleById(Long currentId) {
        Integer role = userMapper.selectRoleById(currentId);
        return role;
    }


    /**
     * 检查手机号是否已注册
     *
     * @param phone
     */
    @Override
    public Boolean checkPhone(String phone) {
        User user = userMapper.selectUserByPhone(phone);
        if (user != null) {
            return true;
        }
        return false;
    }

    /**
     * 用户注册
     *
     * @param userRegisterDTO
     */
    @Override
    public void register(UserRegisterDTO userRegisterDTO) {
        String phone = userRegisterDTO.getPhone();
        String captcha = userRegisterDTO.getCaptcha();
        String password = userRegisterDTO.getPassword();
        // 验证验证码是否正确
        smsUtil.checkCaptcha(phone, captcha);

        // 密码加密
        userRegisterDTO.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        // 插入用户数据
        userRegisterDTO.setNickname(phone);
        userMapper.insert(userRegisterDTO);
    }

    /**
     * 更新用户信息
     *
     * @param userDTO
     */
    @Override
    public void updateUserInfo(UserDTO userDTO) {
        Long userId = BaseContext.getCurrentId();
        // 创建 User 对象
        User user = new User();

        BeanUtils.copyProperties(userDTO, user);
        user.setId(userId);
        // 调用数据更改用户信息
        userMapper.updateUserInfo(user);
/*
        Optional<User> optionalUser = Optional.ofNullable(userMapper.findById(userId));
        if (optionalUser.isPresent()) {
            throw new RuntimeException("用户不存在");
        }

        User user = optionalUser.get();

        // 拷贝允许更新的字段（排除 status 和 id）
        BeanUtils.copyProperties(user, userDTO, "id", "status");*/

    }

    /**
     * 根据id查询用户信息
     *
     * @param currentId
     */
    @Override
    public User findById(Long currentId) {
        User user = userMapper.seletUserById(currentId);
        if (user == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        user.setPassword("******");
        return user;

    }

    /**
     * 修改密码
     * @param passwordDTO
     */
    @Override
    public void updatePassword(PasswordDTO passwordDTO) {
        Long userId = BaseContext.getCurrentId();

        User user = userMapper.findById(userId);
        //判断用户是否存在
        if (user == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        //判断旧密码是否正确
        String oldPassword = DigestUtils.md5DigestAsHex(passwordDTO.getNewPassword().getBytes());
        if (!oldPassword.equals(user.getPassword())) {
            throw new AccountNotFoundException(MessageConstant.PASSWORD_ERROR);
        }
        //  判断两次输入的密码是否一致

        if (!passwordDTO.getNewPassword().equals(passwordDTO.getConfirmPassword())) {
            throw new AccountNotFoundException(MessageConstant.PASSWORD_NOT_SAME);
        }
        //判断原密码和新密码是否相同
        if(passwordDTO.getOldPassword().equals(passwordDTO.getNewPassword())){
            throw new AccountNotFoundException(MessageConstant.PASSWORD_NOT_SAME_WITH_OLD_PASSWORD);
        }

        user.setPassword(DigestUtils.md5DigestAsHex(passwordDTO.getNewPassword().getBytes()));
        userMapper.updateUserInfo(user);
    }

    /**
     * 分页查询
     * @param pageQueryDTO
     * @return
     */
    @Override
    public PageResult page(UerPageQueryDTO pageQueryDTO) {
        PageHelper.startPage(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());
        Page<User> page = userMapper.page(pageQueryDTO);
        page.getResult().forEach(user -> {
            user.setPassword("******");
            user.setPhone(user.getPhone().substring(0, 3) + "****" + user.getPhone().substring(7));
        });
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 更新用户状态
     *
     * @param updateUserDTO
     */
    @Override
    public void updateUserStatus(UpdateUserDTO updateUserDTO) {
       userMapper.updateUserStatus(updateUserDTO);

    }
}
